

## 1. Install the prerequisites
### Install apache, php and php extensions.

sudo apt update -y

sudo apt upgrade

sudo apt install software-properties-common -y

sudo add-apt-repository ppa:ondrej/php

sudo apt install apache2 php8.2 php8.2-{mbstring,xml,memcache,mysql,curl,ldap,sqlite3,zip,memcached} libapache2-mod-php8.2 memcached zip

php -v 


## 2. Install SimpleSAMLphp
### Download SimpleSAMLphp to the /var or desired directory

wget "https://github.com/simplesamlphp/simplesamlphp/releases/download/v2.4.3/simplesamlphp-2.4.3-full.tar.gz"

tar zxf simplesamlphp-2.4.3-full.tar.gz 

sudo mv -v simplesamlphp-2.4.3 /var/simplesamlphp

sudo chown -R root:root /var/simplesamlphp
sudo chown -R www-data:www-data /var/simplesamlphp/public


sudo mkdir /var/simplesamlphp/log
sudo chown www-data:www-data /var/simplesamlphp/log

sudo mkdir /var/simplesamlphp/cache
sudo chown www-data:www-data /var/simplesamlphp/cache


## 3. Configure Apache
### Find the Apache configuration file for the virtual hosts where you want to run SimpleSAMLphp. The configuration may look like this:

sudo vim /etc/apache2/sites-available/simplesamlphp.conf


        <VirtualHost *:80>
                ServerAdmin <admin@example.com>
                ServerName <idp.example.com>
                DocumentRoot /var/simplesamlphp/public/

                SetEnv SIMPLESAMLPHP_CONFIG_DIR /var/simplesamlphp/config

                Alias /simplesaml  /var/simplesamlphp/public/

                <Directory /var/simplesamlphp/public/>
                        Require all granted
                </Directory>

                ErrorLog ${APACHE_LOG_DIR}/error.log
                CustomLog ${APACHE_LOG_DIR}/access.log combined
        </VirtualHost>


sudo a2ensite simplesamlphp.conf

sudo a2dissite 000-default 000-default-le-ssl.conf

sudo systemctl reload apache2



## 4. Deploy SSL
### If SSL is not deployed set the secure flag cookie in config/config.php to false

sudo apt install certbot python3-certbot-apache


sudo certbot --apache


## 5. Configure SimpleSAMLphp
### The main configuration file is located in config/config.php

cd /var/simplesamlphp/

### Create the config file
sudo cp -pv config/config.php.dist config/config.php


### Set a secret salt. Some parts of the SimpleSAMLphp needs this salt to generate cryptographically secure hashes. Generate a random string using this:

openssl rand -base64 32
    GXSzRA3WFATdfUiNWXIOOVSee3wFmNMmjdxv4bk67EM=


###Open the config file with your preferred editor and do the below changes

sudo vim config/config.php

    'baseurlpath' => 'https://<idp.example.com>/simplesaml/',

    'cachedir' => '/var/simplesamlphp/cache/simplesamlphp',

    'loggingdir' => '/var/log/',

    'technicalcontact_name' => 'admin',

    'technicalcontact_email' => '<admin@example.com>',

    'timezone' => 'Africa/Nairobi',

    'secretsalt' => 'GXSzRA3WFATdfUiNWXIOOVSee3wFmNMmjdxv4bk67EM=',

    'auth.adminpassword' => 'password1234',

    'enable.saml20-idp' => true,

    'module.enable' => [
        'core' => true,
        'admin' => true,
        'saml' => true,
        'sqlauth' => true,
    ],

    //Comment out this line
    //50 => 'core:AttributeLimit',


    'store.type' => 'memcache',

    'session.cookie.secure' => true,

    


### Create the authsources and saml20-idp-hosted files from the templates
sudo cp -pv config/authsources.php.dist config/authsources.php

sudo cp -pv metadata/saml20-idp-hosted.php.dist metadata/saml20-idp-hosted.php



### Configure the authentication source

sudo vim config/authsources.php

        //Comment out this block
        'default-sp' => [
                'saml:SP',
                .
                .
                .
                .
        ],

        // Add the a MySQL Authentication block
        mysql-auth' => [
            'sqlauth:SQL',
            'dsn' => 'mysql:host=localhost;port=3307;dbname=simplesamlphp',
            'username' => 'simplesaml',
            'password' => 'passwordyaDB',

            'query' =>[
                "SELECT
                    uid,
                    givenName,
                    email,
                    eduPersonPrincipalName
                FROM
                    users
                WHERE
                    uid = :username
                    AND PASSWORD = SHA2(:password, 512)"
                    AND is_active = TRUE,
            ],
        ],



### Create self signed certificates for signing metadata and SAML assertions

sudo openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out cert/cert.crt -keyout cert/key.pem

sudo openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -out cert/signmd_cert.crt -keyout cert/signmd_key.pem

sudo chown -R www-data: cert/

sudo chmod 400 cert/key.pem

sudo chmod 400 cert/signmd_key.pem



### Configure your IdP

sudo vim metadata/saml20-idp-hosted.php


        $metadata['https://idp.example.com/idp'] = [

            'host' => '__DEFAULT__',

            'privatekey' => 'key.pem',
            'certificate' => 'cert.crt',

            'auth' => 'mysql-auth',

            'saml20.sign.assertion' => true,
            'saml20.sign.response' => true,

            'assertion.encryption' => true,


            'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri',
            'authproc' => [
                10 => [
                    'class' => 'core:AttributeMap',
                    'email' => 'mail',
                ],
                // Convert LDAP names to oids.
                100 => ['class' => 'core:AttributeMap', 'name2oid'],
            ],

            'attributes.required' => true,

            'attributes' => [
                'eduPersonPrincipalName'        => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6',
                'uid'                           => 'urn:oid:0.9.2342.19200300.100.1.1',
                'email'                         => 'urn:oid:1.2.840.113549.1.9.1',
                'givenName'                     => 'urn:oid:2.5.4.42',
                'mail'                          => 'urn:oid:0.9.2342.19200300.100.1.3',
            ],

            'NameIDFormat' => [
                'urn:oasis:names:tc:SAML:2.0:nameid-format:transient',
                'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
            ],

            'SingleSignOnServiceBinding' => ['urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'],
            'SingleLogoutServiceBinding' => [
                'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
                'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
            ],

            'signature.algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
            'signatureAlgorithms' => [
                'http://www.w3.org/2000/09/xmldsig#rsa-sha1',
                'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
                'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512',
            ],

            'sharedkey_algorithm' => ['http://www.w3.org/2001/04/xmlenc#aes128-cbc'],

            'sign.logout' => true,
        ],



### Configure SimpleSAMLphp to sign metadata

sudo vim config/config.php

    'metadata.sign.enable' => true,

    'metadata.sign.privatekey' => '/var/simplesamlphp/cert/signmd_key.pem',
    'metadata.sign.certificate' => '/var/simplesamlphp/cert/signmd_cert.crt',



### Setup MySQL and create a user database

sudo apt install mysql-server

sudo mysql -u root
    CREATE DATABASE simplesamlphp;
    CREATE user 'simplesaml'@'localhost' IDENTIFIED BY 'passwordyaDB';
    GRANT ALL PRIVILEGES ON simplesamlphp.* TO 'simplesaml'@'localhost';

    USE simplesamlphp;


    CREATE TABLE users (
        id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        uid VARCHAR(30) NOT NULL UNIQUE,
        password VARCHAR(255) NOT NULL COMMENT 'Stores encrypted password',
        givenName VARCHAR(100) NOT NULL,
        email VARCHAR(255) NOT NULL,
        eduPersonPrincipalName VARCHAR(255) NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        last_login TIMESTAMP NULL DEFAULT NULL,
        is_active BOOLEAN DEFAULT TRUE,
        
        INDEX idx_uid (uid),
        INDEX idx_email (email),
        INDEX idx_eduPersonPrincipalName (eduPersonPrincipalName),
        INDEX idx_active (is_active)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

    INSERT INTO users (uid, password, givenName, email, eduPersonPrincipalName)
    VALUES 
        (
            'alice_brown',
            SHA2('alicePwd012', 512),
            'Alice Brown',
            'alice.brown@example.com',
            'abrown@school.edu'
        );



    FLUSH PRIVILEGES;
    EXIT;



### Test authentication from the browser
### Go to https://<idp.example.com>/admin and to the "test" tab


### Create your metadata file
sudo cp -pv metadata/saml20-sp-remote.php.dist metadata/saml20-sp-remote.php
sudo vim metadata/saml20-sp-remote.php